package edu.hawaii.examschd;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;
import java.util.Properties;
import edu.hawaii.examschd.modules.Cal;
import edu.hawaii.examschd.modules.ExamScheduler;
import edu.hawaii.examschd.modules.Module;
import edu.hawaii.examschd.modules.CouchDB.CouchDB;

//import edu.hawaii.examschd.modules.ModuleLoader;

public class Core {
  private String NAME = "CORE";
  protected boolean DEBUG = false;
  protected boolean VERBOSE = false;
  protected String DB_TYPE;
  protected String DB_IP;
  protected int DB_PORT;
  protected int SVR_PORT;
  private String configName = "init.ini";

  public static void main(String[] args) {
    Core c = new Core(args);
  }

  /**
   * Begin the program and load modules
   * 
   * @param args
   * 
   */
  public Core(String[] args) {
    boolean loadConfig = true;
    // if there are arguments check if they are valid
    if (args.length > 0) {
      for (String arg : args) {
        // if information is requested, print syntax
        if (arg.equals("?")) {
          print("SYNTAX: ExamSch <configFile>");
          System.exit(0);
        }
        // if it is a config file ending in .properties then load it
        else if (arg.endsWith(".ini")) {
          configName = arg;
        }
        // if they are not valid, exit
        else {
          print("SYNTAX: " + this.getName() + " <configFile>");
          System.exit(0);
        }
      }
    }
    // load config file
    Properties configFile = new Properties();
    try {
      if (VERBOSE) {
        print("Loading config file: " + configName);
      }
      File config = new File(configName);
      FileInputStream fis = new FileInputStream(config);
      configFile.load(fis);
    }
    catch (IOException e) {
      print("WARNING: Config file " + configName + " not found.");
      loadConfig = false;
    }
    if (loadConfig) {
      // Load variables from config file
      DEBUG = Boolean.parseBoolean(configFile.getProperty("DEBUG"));
      VERBOSE = Boolean.parseBoolean(configFile.getProperty("VERBOSE"));
      DB_TYPE = configFile.getProperty("DB_TYPE");
      DB_IP = configFile.getProperty("DB_IP");
      DB_PORT = Integer.parseInt(configFile.getProperty("DB_PORT"));
      SVR_PORT = Integer.parseInt(configFile.getProperty("SVR_PORT"));
      // if debug is set, enable verbose as well
      if (DEBUG) {
        VERBOSE = true;
      }
      // if verbose is set then print the loaded values from the config
      if (VERBOSE) {
        print("DEBUG: " + DEBUG);
        print("VERBOSE: " + VERBOSE);
        print("DB_TYPE: " + DB_TYPE);
        print("DB_IP: " + DB_IP);
        print("DB_PORT: " + DB_PORT);
      }
    }
    // Load modules
    // List<Module> modules = ModuleLoader.loadModules();
    //
    // for (Module module : modules) {
    // if (VERBOSE) {
    // print("Loading : " + module.getName());
    // }
    // module.load();
    // module.syncVars(DEBUG, VERBOSE);
    // }
    // Start our application
    if (VERBOSE) {
      print("Starting application...");
    }
    startApp();

    // //cleanup and unload modules
    // for (Module module : modules) {
    // module.unload();
    // }
  }

  /**
   * Name of the application, allows for module to be extended
   * 
   * @return the name of the application
   */
  private String getName() {
    return NAME;
  }

  /**
   * Start the application
   */
  private void startApp() {
    // manually boot modules;
    ExamScheduler dbi = new CouchDB();
    Console console = new Console(dbi);
    console.start();
    // Server server = new Server(SVR_PORT);
    // server.start();
  }

  /**
   * Unified print method for adjusting how messages are output.
   * 
   * @param data String to be printed
   * @return 0 if there is an error, else 1
   */
  public static void print(String data) {
    try {
      System.out.println(data);
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }
}